﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace ufida.u9.cust.dz.beplugin.Utils
{
    internal class URLEncoder
    {  // 不需要编码的字符集合
        private static readonly bool[] _unreservedChars = CreateUnreservedChars();

        /// <summary>
        /// 初始化不需要编码的字符集合
        /// </summary>
        private static bool[] CreateUnreservedChars()
        {
            var chars = new bool[256];

            // 字母A-Z
            for (int i = 'A'; i <= 'Z'; i++)
                chars[i] = true;

            // 字母a-z
            for (int i = 'a'; i <= 'z'; i++)
                chars[i] = true;

            // 数字0-9
            for (int i = '0'; i <= '9'; i++)
                chars[i] = true;

            // 特殊字符: - _ . ~
            chars['-'] = true;
            chars['_'] = true;
            chars['.'] = true;
            chars['~'] = true;

            return chars;
        }

        /// <summary>
        /// 对字符串进行URL编码
        /// </summary>
        /// <param name="value">需要编码的字符串</param>
        /// <param name="encoding">编码方式，默认为UTF-8</param>
        /// <returns>编码后的字符串</returns>
        public static string Encode(string value, Encoding encoding = null)
        {
            if (string.IsNullOrEmpty(value))
                return string.Empty;

            // 设置默认编码为UTF-8
            encoding = encoding ?? Encoding.UTF8;

            // 将字符串转换为字节数组
            byte[] bytes = encoding.GetBytes(value);
            var result = new StringBuilder(bytes.Length * 3);

            // 十六进制字符
            char[] hexChars = "0123456789ABCDEF".ToCharArray();

            foreach (byte b in bytes)
            {
                // 不需要编码的字符直接添加
                if (_unreservedChars[b])
                {
                    result.Append((char)b);
                }
                // 空格特殊处理为+
                else if (b == 0x20)
                {
                    result.Append('+');
                }
                // 其他字符编码为%XX格式
                else
                {
                    result.Append('%');
                    result.Append(hexChars[b >> 4]);    // 高4位
                    result.Append(hexChars[b & 0x0F]);  // 低4位
                }
            }

            return result.ToString();
        }
    }
}
